#include "Engine.hpp"

void Engine::setClock(IClock* clock)
{
	// Create our timekeeper object using the given clock
	m_timekeeper = new TimeKeeper<Engine>(this, clock);
}

void Engine::start()
{
	// Check that the engine components have been assigned
	if( !m_timekeeper ) throw EngineException("No clock object set");
	if( !m_input )      throw EngineException("No input object set");
	//if( !m_network )    throw EngineException("No network object set");
	//if( !m_world )      throw EngineException("No world object set");
	if( !m_renderer )   throw EngineException("No renderer object set");
	
	// Check that all the handlers have been assigned
	if( !m_tick_handler ) throw EngineException("No tick handler set");
	if( !m_input_handler ) throw EngineException("No input handler set");
	//if( !m_network_handler ) throw EngineException("No network handler set");
	//if( !m_physics_handler ) throw EngineException("No physics handler set");
	if( !m_renderer_handler ) throw EngineException("No renderer handler set");
	
	// Start the timekeeper, which will call our time events
	m_timekeeper->start();
}

void Engine::onMoment(TimeKeeper<Engine>* caller)
{
	m_input->update();
	//m_network->update();
	//m_world->update();
	m_renderer->update();
}
void Engine::onTick(TimeKeeper<Engine>* caller)
{
	// Pass the engine's own tick event to its handler
	m_tick_handler->onTick();
}

// Forward events from engine components to handlers
// Note: Engine-based responses could be added too
void Engine::onKeyDown(IInput* caller, Key key)
{ m_input_handler->onKeyDown(caller, key);} 
void Engine::onKeyUp(IInput* caller, Key key)
{ m_input_handler->onKeyUp(caller, key); }
void Engine::onMouseDown(IInput* caller, Vector pos, Button button)
{ m_input_handler->onMouseDown(caller, pos, button); }
void Engine::onMouseUp(IInput* caller, Vector pos, Button button)
{ m_input_handler->onMouseUp(caller, pos, button); }
void Engine::onMouseMove(IInput* caller, Vector pos, Button button)
{ m_input_handler->onMouseMove(caller, pos, button); }
void Engine::onQuit(IInput* caller)
{ m_input_handler->onQuit(caller); }
void Engine::onFrame(IRenderer* caller)
{ m_renderer_handler->onFrame(caller); }
